package com.wysiwyg.admin.config.producer;

import com.alibaba.fastjson2.JSON;
import com.wysiwyg.flow.constants.MessageConstants;
import com.wysiwyg.flow.enums.FlowEventEnum;
import com.wysiwyg.flow.enums.FlowTag;
import com.wysiwyg.flow.model.dto.FlowMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class FlowMessageProducer {

    private final RocketMQTemplate rocketMQTemplate;

    public <T> void sendSync(FlowEventEnum eventType, String businessKey, T payload) {
        FlowMessage<T> flowMessage = buildMessage(eventType, null, businessKey, payload);
        String destination = MessageConstants.FLOW_TOPIC + ":" + eventType.name();
        SendResult result = rocketMQTemplate.syncSend(destination, MessageBuilder.withPayload(JSON.toJSONString(flowMessage)).build());
        log.info("Flow message sent sync. destination={}, result={}", destination, result);
    }

    public <T> void sendAsync(FlowEventEnum eventType, String businessKey, T payload) {
        sendAsync(eventType, null, businessKey, payload, null, null);
    }

    /**
     * 发送异步消息，支持自定义成功和失败回调
     * @param eventType 事件类型
     * @param tag 业务流程标签
     * @param businessKey 业务键
     * @param payload 消息载荷
     * @param onSuccess 成功回调（可选）
     * @param onFailure 失败回调（可选）
     */
    public <T> void sendAsync(FlowEventEnum eventType, FlowTag tag, String businessKey, T payload,
                             SendCallback onSuccess, SendCallback onFailure) {
        FlowMessage<T> flowMessage = buildMessage(eventType, tag, businessKey, payload);
        String destination = MessageConstants.FLOW_TOPIC + ":" + eventType.name();

        SendCallback callback = new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("Flow message sent async success. destination={}, result={}", destination, sendResult);
                if (onSuccess != null) {
                    onSuccess.onSuccess(sendResult);
                }
            }

            @Override
            public void onException(Throwable e) {
                log.error("Flow message sent async failed. destination={}", destination, e);
                if (onFailure != null) {
                    onFailure.onException(e);
                }
            }
        };

        rocketMQTemplate.asyncSend(destination,
            MessageBuilder.withPayload(JSON.toJSONString(flowMessage)).build(),
            callback);
    }

    private <T> FlowMessage<T> buildMessage(FlowEventEnum eventType, FlowTag tag, String businessKey, T payload) {
        FlowMessage<T> message = new FlowMessage<>();
        message.setEventType(eventType);
        message.setTag(tag);
        message.setBusinessKey(businessKey);
        message.setPayload(payload);
        return message;
    }
}
